Skip to content

feat(view): export plotted data (CSV/XLSX) and plot (HTML) - #5

Merged
simontaurus merged 1 commit into
mainfrom
feat/archive-export
Jul 23, 2026
Merged

feat(view): export plotted data (CSV/XLSX) and plot (HTML)#5
simontaurus merged 1 commit into
mainfrom
feat/archive-export

Conversation

@simontaurus

Copy link
Copy Markdown
Contributor

Summary

Adds a dashboard-level Export section (compact collapsible card in Plot Controls) to the archive views (DataToolView, ProcessObjectView; LiveDataToolView keeps working) with three FileDownload actions on BaseDataView. Additive and backward compatible.

Download CSV / XLSX

A unit-aware pint-pandas table of every checked channel:

  • Numeric channels become pint columns in the selected display unit; text-log channels become plain object columns (so channels from a different display group are included too).
  • A tolerant _dequantify writes a two-row (label, unit) header; column keys stay unit-free.
  • Rows capped at EXPORT_MAX_ROWS (1,000,000) via uniform downsampling (logged).
  • Composite sub-fields get unique labels, with a dedupe safety net so duplicate names cannot collapse a column.

Download plot (HTML)

A standalone interactive Bokeh file:

  • Figures are rebuilt fresh and detached (a model may live in only one document) and pinned to a fixed frame size so they render outside a sizing container.
  • The log console is embedded below the plots as a width-matched, scrollable Div.

Extensibility

Views supply export_series() (tidy records) and _make_figures/_export_figures hooks; the public figures property still exposes the live figures for host annotation. Export deps (pandas, pint-pandas, openpyxl) are an optional export extra, imported lazily; buttons disable with a hint when absent.

Tests

  • Unit tests: DataFrame build + alignment, dequantify, row cap, text column, label dedup.
  • Playwright browser tests: download the CSV and HTML and assert the unit header, the text channel, the embedded log console, and a rendered (non-collapsed) plot. They self-skip without Playwright/Chromium (export extra + Chromium are not in CI), so they run locally/manually.
  • Full offline suite green; flake8 clean. Local *.sqlite databases are gitignored.

Browser testing surfaced (and this PR fixes) three real bugs: composite-label column collapse, the file_html shared-document error, and the collapsed standalone-HTML plot frame.

Notes

Follow-up (tracked separately): factor the pint/CSV table logic into a generic TabularData base in opensemantic.core and reuse it from both this export and opensemantic.characteristics.quantitative.

Add a dashboard-level Export section (compact collapsible card in Plot
Controls) with three FileDownload actions on BaseDataView:

- Download CSV / XLSX: a unit-aware, pint-pandas table of every checked
  channel. Numeric channels become pint columns (in the selected display
  unit); text-log channels become plain object columns; a tolerant
  dequantify writes a two-row (label, unit) header. Rows are capped at
  EXPORT_MAX_ROWS via uniform downsampling. Composite sub-fields get
  unique labels, with a dedupe safety net so duplicate names cannot
  collapse a column into a DataFrame.
- Download plot (HTML): a standalone interactive Bokeh file. Figures are
  rebuilt fresh and detached (a model may live in only one document) and
  pinned to a fixed frame size so they render outside a sizing container.
  The log console is embedded below the plots as a width-matched,
  scrollable Div.

Views supply export_series() (tidy records) and _make_figures/
_export_figures hooks; the public figures property still exposes the
live figures for host annotation. Export deps (pandas, pint-pandas,
openpyxl) are an optional 'export' extra, imported lazily; buttons
disable with a hint when absent.

Tests: unit tests for the DataFrame build, dequantify, row cap, text
column and label dedup; Playwright browser tests that download the CSV
and HTML and assert the unit header, text channel, embedded log console
and a rendered (non-collapsed) plot. Browser tests self-skip without
Playwright/Chromium. Local *.sqlite databases are gitignored.
@simontaurus
simontaurus merged commit f859edd into main Jul 23, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant